<!--
 * @Author: WuFeng <763467339@qq.com>
 * @Date: 2024-11-25 11:06:56
 * @LastEditTime: 2024-11-25 11:07:28
 * @LastEditors: WuFeng <763467339@qq.com>
 * @Description: 
 * @FilePath: \markdown-magic\src\pages\Pdf\page\entry\editor\setTempleteBak.vue
 * Copyright 版权声明
-->
<template>
  <div class="pageWrap">
    <div class="handleWrap">
      <a-space>
        <a-button type="primary" @click="handleGenerate">生成</a-button>
        <a-button type="primary" ghost @click="handleDownload">下载</a-button>
      </a-space>
    </div>
    <div v-for="page in state.pdfPages" :key="page" class="pageItem" :id="`pageItem${page}`">
      <div :id="`textLayer${page}`" class="textLayer" :class="`textLayer`"></div>
      <div :id="`annotationsLayer${page}`" class="annotationsLayer"></div>
      <canvas :id="`pdfCanvas${page}`" />
      <canvas 
        ref="overlayCanvasRefs" 
        style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;z-index:999;"
        @mousedown="(e) => startDrawing(e, page)" 
        @mousemove="(e) => draw(e, page)" 
        @mouseup="(e) => endDrawing(e, page)">
      </canvas>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, defineEmits, computed, onMounted, nextTick } from 'vue'
import { message } from 'ant-design-vue'

import { PDFDocument, rgb } from 'pdf-lib'

import * as PDF from 'pdfjs-dist'
import * as workerSrc from 'pdfjs-dist/build/pdf.worker.min?url'

import $ from 'jquery'

import { TextLayerBuilder } from 'pdfjs-dist/web/pdf_viewer'
import 'pdfjs-dist/web/pdf_viewer.css'

import download from 'downloadjs'

PDF.GlobalWorkerOptions.workerSrc = workerSrc.default

// const pdf = './pdf_加水印.pdf'
// const pdfPath = '/pdf.pdf'
const pdfPath = '/pdf.form.pdf'

const state = reactive<any>({
  pdfPath, // 本地PDF文件路径放在/public中
  pdfPages: '', // 页数
  pdfWidth: '', // 宽度
  pdfSrc: '', // 地址
  pdfScale: 1.5, // 放大倍数
})
let pdfDoc: any = null
onMounted(() => {
  loadFile(state.pdfPath)
})
function loadFile(url: string) {
  PDF.getDocument(url).promise.then((p: any) => {
    pdfDoc = p
    const { numPages } = p
    state.pdfPages = numPages
    nextTick(() => {
      renderPage(1) // 从第一页开始渲染
    })
  })
}
function renderPage(num: number) {
  pdfDoc.getPage(num).then(async (page: any) => {
    const canvas: any = document.getElementById(`pdfCanvas${num}`)
    const ctx = canvas.getContext('2d')
    const dpr = window.devicePixelRatio || 1
    const bsr
        = ctx.webkitBackingStorePixelRatio
        || ctx.mozBackingStorePixelRatio
        || ctx.msBackingStorePixelRatio
        || ctx.oBackingStorePixelRatio
        || ctx.backingStorePixelRatio
        || 1
    const ratio = dpr / bsr
    const viewport = page.getViewport({ scale: state.pdfScale })
    canvas.width = viewport.width * ratio
    canvas.height = viewport.height * ratio
    canvas.style.width = '100%'
    canvas.style.height = '100%'
    state.pdfWidth = `${viewport.width}px`
    ctx.setTransform(ratio, 0, 0, ratio, 0, 0)
    // 将 PDF 页面渲染到 canvas 上下文中
    const renderContext = {
      canvasContext: ctx,
      viewport,
    }
    // page.render(renderContext)
    await page.render(renderContext)

    // 添加文字层
    const textContent = await page.getTextContent()
    const textLayer = new PDF.TextLayer({
      textContentSource: textContent,
      viewport,
      container: document.getElementById('textLayer' + num),
    })
    await textLayer.render()

    // 添加注释层
    const annotationsContainer = document.getElementById('annotationsLayer' + num)
    annotationsContainer.innerHTML = '' // Clear the previous annotations
    page.getAnnotations().then((annotations) => {
      console.log(`🚀 ~ page.getAnnotations ~ annotations:`, annotations)
      annotations.forEach((annotation) => {
        // 过滤出表单字段（subtype 为 'Widget'）
        if (annotation.subtype === 'Widget') {
          // formFieldsList.push({
          //   name: annotation.FieldName,
          //   fieldType: annotation.FieldType,
          //   value: annotation.fieldValue
          // });
          const rect = annotation.rect;
          const transformedRect = viewport.convertToViewportRectangle(rect)
          const annotationElement = document.createElement('div')
          annotationElement.style.position = 'absolute'
          annotationElement.style.left = `${transformedRect[0]}px`
          annotationElement.style.top = `${transformedRect[1]}px`
          annotationElement.style.width = `${transformedRect[2] - transformedRect[0]}px`
          annotationElement.style.height = `${transformedRect[3] - transformedRect[1]}px`
          annotationElement.style.border = '1px dashed blue'
          annotationElement.style.backgroundColor = 'rgba(255, 255, 0, 0.9)'
          annotationElement.style.pointerEvents = 'auto'
          annotationElement.title = JSON.stringify(annotation, null, 2) // Show annotation details on hover
          annotationsContainer.appendChild(annotationElement)
        }
      })
    })

    // overlayCanvasRefs
    overlayCanvasRefs.value[num - 1].width = viewport.width * ratio
    overlayCanvasRefs.value[num - 1].height = viewport.height * ratio

    if (state.pdfPages > num)
      renderPage(num + 1)
  })
}

const overlayCanvasRefs = ref([])
const drawInfo = reactive({
  rectangles: [],
  // 页码
  pageNum: 1,
  // 绘制状态
  isDrawing: false,
  // 开始绘制的x、y坐标
  startX: 0,
  startY: 0,
  // 结束绘制的x、y坐标
  endX: 0,
  endY: 0,
})

// 开始绘制
const startDrawing = (event, num) => {
  // console.log(`🚀 ~ startDrawing ~ num:`, num)
  // console.log(`🚀 ~ overlayCanvasRefs:`, overlayCanvasRefs)
  // console.log(`🚀 ~ startDrawing ~ event:`, event)
  drawInfo.pageNum = num
  drawInfo.isDrawing = true
  drawInfo.startX = event.offsetX
  drawInfo.startY = event.offsetY
}

// 绘制
const draw = (event) => {
  if (!drawInfo.isDrawing)
    return
  
  const currentOverlayCanvasRef = overlayCanvasRefs.value[drawInfo.pageNum - 1]
  const ctx = currentOverlayCanvasRef!.getContext('2d')
  // console.log(`🚀 ~ draw ~ ctx:`, ctx)
  ctx?.clearRect(0, 0, currentOverlayCanvasRef!.width, currentOverlayCanvasRef!.height)
  drawAllRectangles(currentOverlayCanvasRef)
  const currentX = event.offsetX
  const currentY = event.offsetY
  const width = currentX - drawInfo.startX
  const height = currentY - drawInfo.startY
  ctx!.strokeStyle = 'rgb(228, 228, 228)'
  ctx!.lineWidth = 2
  ctx?.strokeRect(drawInfo.startX, drawInfo.startY, width, height)
}

// 结束绘制
const endDrawing = (event) => {
  // console.log(`🚀 ~ endDrawing ~ endDrawing:`)
  const currentOverlayCanvasRef = overlayCanvasRefs.value[drawInfo.pageNum - 1]
  drawInfo.isDrawing = false
  drawInfo.endX = event.offsetX
  drawInfo.endY = event.offsetY
  drawInfo.rectangles.push({
    x: drawInfo.startX,
    y: drawInfo.startY,
    width: event.offsetX - drawInfo.startX,
    height: event.offsetY - drawInfo.startY,
    fieldName: Math.random()
  })
  drawAllRectangles(currentOverlayCanvasRef)
}

// 渲染所有区域
const drawAllRectangles = (overlayCanvas) => {
  const ctx = overlayCanvas!.getContext('2d')
  ctx?.clearRect(0, 0, overlayCanvas!.width, overlayCanvas!.height)
  drawInfo.rectangles.forEach(rect => {
    ctx!.strokeStyle = 'rgb(0, 0, 0)'

    ctx!.lineWidth = 4
    ctx!.strokeRect(rect.x, rect.y, rect.width, rect.height)
    ctx!.fillStyle = 'rgb(221, 228, 255)'
    ctx!.fillRect(rect.x, rect.y, rect.width, rect.height)
    ctx!.font = '20px Arial'
    ctx!.textBaseline = 'middle'
    ctx!.fillStyle = 'rgb(0, 0, 0)'

    ctx!.fillText(rect.fieldName, rect.x + rect.width / 2, rect.y + 20, rect.width) // 修正文本位置，以便不会超出矩形
  })

}

// 生成
const handleGenerate = async () => {
  const pdfLibDoc = await PDFDocument.load(await pdfDoc.getData())
  console.log(`🚀 ~ axios.get ~ pdfLibDoc:`, pdfLibDoc)
  const page = pdfLibDoc.getPages()[0];
  console.log(`🚀 ~ handleGenerate ~ page:`, page)
  const { height: pdfHeight } = page.getSize();
  console.log(`🚀 ~ handleGenerate ~ pdfHeight:`, pdfHeight)

  const form = pdfLibDoc.getForm()
  console.log(`🚀 ~ handleGenerate ~ form:`, form)

  

  drawInfo.rectangles.forEach((rect) => {
    console.log(`🚀 ~ drawInfo.rectangles.forEach ~ rect:`, rect)
    const field = form.createTextField(`${rect.fieldName}`);
    field.setText(`${rect.fieldName}`);
    field.addToPage(page, {
      x: rect.x,  // 使用缩放后的X坐标
      y: rect.y,  // 使用调整后的Y坐标
      width: rect.width,  // 使用缩放后的宽度
      height: rect.height,  // 使用缩放后的高度
      backgroundColor: rgb(0.95, 0.95, 0.95),
      borderColor: rgb(1, 1, 1),
      borderWidth: 1
    })
  })

  const pdfBytes = await pdfLibDoc.save()
  console.log(`🚀 ~ handleGenerate ~ pdfBytes:`, pdfBytes)
  download(pdfBytes, 'download.pdf', 'application/pdf')
}

// 下载
const handleDownload = () => {
}

</script>

<style lang="scss" scoped>
html, body{
  width: 100%;
  height: 100%;
}
</style>
<style lang="scss" scoped>
.pageWrap{
  .handleWrap{
    padding: 0 12px 12px 12px;
    display: flex;
    justify-content: flex-end;
  }
  .pageItem{
    position: relative;
    border: 1px solid #d4d2d2;
    margin-bottom: 8px;
    .textLayer,
    .annotationsLayer{
      position: absolute;
      left: 0;
      right: 0;
      top: 0;
      bottom: 0;
      // pointer-events: none;
      // width: 100%;
      // height: 100%;
    }
  }
}
</style>